/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package com.alxbrendmaquinarias.controller.operation;

import com.alxbrendmaquinarias.model.Client;
import com.alxbrendmaquinarias.model.DetailSaleProduct;
import com.alxbrendmaquinarias.model.Employee;
import com.alxbrendmaquinarias.model.Product;
import com.alxbrendmaquinarias.model.ProductShop;
import com.alxbrendmaquinarias.model.SaleProduct;
import com.alxbrendmaquinarias.model.Shop;
import com.alxbrendmaquinarias.service.ClientService;
import com.alxbrendmaquinarias.service.ProductShopService;
import com.alxbrendmaquinarias.service.SaleProductService;
import com.alxbrendmaquinarias.service.ShopService;
import com.alxbrendmaquinarias.util.ValidateUtil;
import com.alxbrendmaquinarias.util.VarUtil;
import com.alxbrendmaquinarias.util.faces.FacesUtil;
import java.io.Serializable;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import org.omnifaces.util.Faces;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/** 
 *
 * @author jorge
 */ 
@Controller
public class SaleDocumentsController implements Serializable{
    
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    
    @Autowired
    ClientService clientService;
    @Autowired
    ProductShopService productShopService;
    @Autowired
    ShopService shopService;
    @Autowired
    SaleProductService saleProductService;
    
    private Client client = new Client();
    private ProductShop productShop = new ProductShop();
    private DetailSaleProduct detailSaleProduct = new DetailSaleProduct();
    private Shop shop = new Shop();
    private SaleProduct saleProduct = new SaleProduct();
    
    private List<Client> listClient;
    private List<ProductShop> listProductShop;
    private List<DetailSaleProduct> listDetailSaleProduct;

    private String showDate;
    private double calculateIgv;
    private double calculateTotalAmount;
    private double calculateSubTotal;
    private String searchForCode = "";
    private String searchForName = "";
    private Map<String, Object> parameters = null;
    private String namedQuery = "ProductShop.findAll";
    private LazyDataModel<ProductShop> lazyModelProductShop;
    private Map<String, Object> mapParam = null;
    
    
    
    public SaleDocumentsController() {
    }
    
    public void initValuesSaleDocument()
    {
        client = new Client();
        listClient = null;
        productShop = new ProductShop();
        productShop.setProductId(new Product());
        listProductShop = null;
        detailSaleProduct = new DetailSaleProduct();
        listDetailSaleProduct = null;
        saleProduct = new SaleProduct();
        this.calculateIgv = 0.0;
        this.calculateSubTotal = 0.0;
        this.calculateTotalAmount = 0.0;
        lazyModelProductShop = null;
    }
    
    public void initValuesProductShop()
    {
        productShop = new ProductShop();
        productShop.setProductId(new Product());
    }
    
    public void initValuesDetailProducShop()
    {
        detailSaleProduct = new DetailSaleProduct();
    }
    
    public void CleanObjectProductShop(){
        
        productShop = new ProductShop();
        productShop.setProductId(new Product());
        detailSaleProduct.setAmount(null);
        detailSaleProduct.setPriceUnit(null);
    }
    
    private boolean ExistProductInTableDetail()
    {
        boolean flag=false;
        for(DetailSaleProduct dsp: this.listDetailSaleProduct)
        {
            if(dsp.getProductId().getProductId().equals(productShop.getProductId().getProductId()))
            {
                flag = true;
                System.out.println("Producto existe");
            }
        }
        return flag;
    }
  
    ////////////////////////////////////
    /// METHOD ADD BASKET - TICKET    //
    ////////////////////////////////////
    public void addProductToBasket()
    {
        if(!ValidateUtil.isString(productShop.getProductId().getFullName()))
        {
            System.out.println("fullName="+productShop.getProductId().getFullName());
            if(!ValidateUtil.isInteger(detailSaleProduct.getAmount()))
            {
                System.out.println("amount="+detailSaleProduct.getAmount());
                if(!ValidateUtil.isDouble(detailSaleProduct.getPriceUnit()))
                {
                    System.out.println("priceUnit="+detailSaleProduct.getPriceUnit());
                    if(listDetailSaleProduct==null)
                    {
                        listDetailSaleProduct = new ArrayList<DetailSaleProduct>();
                        detailSaleProduct.setProductId(productShop.getProductId());
                        //se cambio listProductShop por lazyModelProductShop
                        for(ProductShop ps: lazyModelProductShop){
                            if(ps.getProductId().equals(detailSaleProduct.getProductId())){
                                System.out.println("====================");
                                System.out.println("stock anterior "+ps.getAmount());
                                ps.setAmount(ps.getAmount()-detailSaleProduct.getAmount());
                                System.out.println("====================");
                                System.out.println("stock actualizado "+ps.getAmount());
                            }
                        }
                        listDetailSaleProduct.add(detailSaleProduct);
                        initValuesProductShop();
                        initValuesDetailProducShop();
                    }else{
                        if(!ExistProductInTableDetail())
                        {
                            detailSaleProduct.setProductId(productShop.getProductId());
                            listDetailSaleProduct.add(detailSaleProduct);
                            //se cambio listProductShop por lazyModelProductShop
                            for(ProductShop ps: lazyModelProductShop){
                                if(ps.getProductId().equals(detailSaleProduct.getProductId())){
                                    ps.setAmount(ps.getAmount()-detailSaleProduct.getAmount());
                                }
                            }
                            initValuesProductShop();
                            initValuesDetailProducShop();
                        }else{
                            for(DetailSaleProduct dsp: listDetailSaleProduct){
                                if(dsp.getProductId().equals(productShop.getProductId())){
                                    System.out.println("antes - dsp.getAmount()="+dsp.getAmount());
                                    dsp.setAmount(dsp.getAmount()+detailSaleProduct.getAmount());
                                    System.out.println("detailSaleProduct.getAmount()="+detailSaleProduct.getAmount());
                                    System.out.println("despues - dsp.getAmount()="+dsp.getAmount());
                                    productShop.setAmount(productShop.getAmount()-detailSaleProduct.getAmount());
                                    System.out.println("saldo en productShop="+productShop.getAmount());
                                    dsp.setPriceUnit(detailSaleProduct.getPriceUnit());
                                    initValuesProductShop();
                                    initValuesDetailProducShop();
                                }
                            }
                        }
                    }// END IF INITIAL   
                }else{
                    FacesUtil.addMessage("Ingrese Precio Unitario", null, FacesMessage.SEVERITY_WARN);
                }
            }else{
                FacesUtil.addMessage("Ingrese Cantidad", null, FacesMessage.SEVERITY_WARN);
            }
        }else{
            FacesUtil.addMessage("Busque Producto", null, FacesMessage.SEVERITY_WARN);
        }
        
    }
    
    ////////////////////////////////////
    ///   METHOD REMOVE - TICKET      //
    ////////////////////////////////////
    public void removeSalProductDetail(DetailSaleProduct detail)
    {
        //se cambio listProductShop por lazyModelProductShop
        for(ProductShop ps: lazyModelProductShop){
            if(ps.getProductId().equals(detail.getProductId())){
                ps.setAmount(ps.getAmount()+detail.getAmount());
            }
        }
        
        for (int i = 0; i < listDetailSaleProduct.size(); i++) {
            if(listDetailSaleProduct.get(i).getProductId().getProductId().equals(detail.getProductId().getProductId())){
                listDetailSaleProduct.remove(i);
                initValuesProductShop();
                break;
            }
        }
    }
    
    ////////////////////////////////////
    //     METHOD UPDATE - TICKET     //
    ////////////////////////////////////
    public void updateSaleProductDetail()
    {
        detailSaleProduct.setAmount(detailSaleProduct.getAmount());
        detailSaleProduct.setPriceUnit(detailSaleProduct.getPriceUnit());
        initValuesProductShop();
        initValuesDetailProducShop();
    }
    
    ////////////////////////////////////
    ///     METHOD SAVE - TICKET      //
    ////////////////////////////////////
    public void saveTicket()throws Exception
    {
        try {
            if(listDetailSaleProduct!=null)
            {
                Employee employee = (Employee) Faces.getSessionAttribute(FacesUtil.ATTRIBUTE_USER);
                saleProduct.setEmployeeId(employee);
                saleProduct.setClientId(client);
                saleProduct.setDocumentType("B");
                saleProduct.setDetailSaleProductList(listDetailSaleProduct);
                saleProduct.setTotalAmount(getCalculateSubTotal());
                //se cambio listProductShop por lazyModelProductShop
                for(ProductShop ps: lazyModelProductShop)
                {
                    System.out.println("update productShop="+ps.getAmount());
                    productShopService.update(ps);
                }
                saleProductService.save(saleProduct);
                FacesUtil.addMessage("Guardado con éxito...", null, FacesMessage.SEVERITY_INFO);
                initValuesSaleDocument();
            }else{
                FacesUtil.addMessage("No existe datos", null, FacesMessage.SEVERITY_WARN);
            }
        } catch (Exception e) {
        }
 
    }
    
    ////////////////////////////////////
    ///     METHOD SAVE - INVOICE     //
    ////////////////////////////////////
    public void saveInvoice()throws Exception
    {
        try {
            if(listDetailSaleProduct!=null)
            {
                Employee employee = (Employee) Faces.getSessionAttribute(FacesUtil.ATTRIBUTE_USER);
                saleProduct.setEmployeeId(employee);
                saleProduct.setClientId(client);
                saleProduct.setDocumentType("F");
                saleProduct.setSubTotal(getCalculateSubTotal());
                saleProduct.setTotalAmount(getCalculateTotalAmount());
                saleProduct.setDetailSaleProductList(listDetailSaleProduct);
                //se cambio listProductShop por lazyModelProductShop
                for(ProductShop ps: lazyModelProductShop)
                {
                    System.out.println("update productShop="+ps.getAmount());
                    productShopService.update(ps);
                }
                saleProductService.save(saleProduct);
                FacesUtil.addMessage("Guardado con éxito...", null, FacesMessage.SEVERITY_INFO);
                initValuesSaleDocument();
            }else{
                FacesUtil.addMessage("No existe datos", null, FacesMessage.SEVERITY_WARN);
            }
        } catch (Exception e) {
        }
  
    }
    
    //METHOD THAT PAYLOAD PRODUCTSHOP
    public LazyDataModel<ProductShop> getLazyModelProductShop() throws Exception {
        if (lazyModelProductShop == null) {
            lazyModelProductShop = new LazyDataModel<ProductShop>() {
                
                @Override
                public List<ProductShop> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
                    //return super.load(first, pageSize, sortField, sortOrder, filters); //To change body of generated methods, choose Tools | Templates.

                    List<ProductShop> lazyPS;
                    try {
                        
                        lazyPS = productShopService.listLazy(namedQuery, getParameters(), first, pageSize);
                    } catch (Exception ex) {
                        lazyPS = new ArrayList<>();
                        //Logger.getLogger(InputProductController.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    return lazyPS;
                }
                
            };
            lazyModelProductShop.setRowCount(productShopService.count("ProductShop.count", getMapParam()));
        }
        
        return lazyModelProductShop;
    }
    
    
    //SEARCH PRODUCT SHOP BY CODE OR NAME
    public void obtainLazy() {
        if (searchForCode.isEmpty() && searchForName.isEmpty()) {
            setNamedQuery("ProductShop.findAll");
            parameters = new HashMap<>();
            parameters.put("shopId", shop.getId());
        } else if (searchForName.isEmpty()) {
            setNamedQuery("ProductShop.findCode");
            parameters = new HashMap<>();
            parameters.put("code", "%" + searchForCode + "%");
            parameters.put("shopId", shop.getId());
        } else if (searchForCode.isEmpty()) {
            setNamedQuery("ProductShop.findName");
            parameters = new HashMap<>();
            parameters.put("name", "%" + searchForName + "%");
            parameters.put("shopId", shop.getId());
        } else {
            setNamedQuery("ProductShop.findCodeName");
            parameters = new HashMap<>();
            parameters.put("code", "%" + searchForCode + "%");
            parameters.put("name", "%" + searchForName + "%");
            parameters.put("shopId", shop.getId());
        }
    }
    
    public Client getClient(){
        return client;
    }

    public void setClient(Client client) {
        this.client = client;
    }

    public List<Client> getListClient() throws Exception{
        if(listClient == null)
        {
            listClient = clientService.list("Client.findAll");
        }
        return listClient;
    }

    public void setListClient(List<Client> listClient) {
        this.listClient = listClient;
    }

    public ProductShop getProductShop() {
        return productShop;
    }

    public void setProductShop(ProductShop productShop) {
        this.productShop = productShop;
    }

    public List<ProductShop> getListProductShop() {
        if(listProductShop==null)
        {
            Employee employee = (Employee) Faces.getSessionAttribute(FacesUtil.ATTRIBUTE_USER);
            listProductShop = productShopService.list("SELECT * FROM product_shop WHERE shop_id = "+employee.getShopId().getId());   
        }
        return listProductShop;
    }

    public void setListProductShop(List<ProductShop> listProductShop) {
        this.listProductShop = listProductShop;
    }

    public DetailSaleProduct getDetailSaleProduct() {
        return detailSaleProduct;
    }

    public void setDetailSaleProduct(DetailSaleProduct detailSaleProduct) {
        this.detailSaleProduct = detailSaleProduct;
    }

    public List<DetailSaleProduct> getListDetailSaleProduct() {
        return listDetailSaleProduct;
    }

    public void setListDetailSaleProduct(List<DetailSaleProduct> listDetailSaleProduct) {
        this.listDetailSaleProduct = listDetailSaleProduct;
    }

    public Shop getShop() {
        try {
            Employee employee = (Employee) Faces.getSessionAttribute(FacesUtil.ATTRIBUTE_USER);
        shop = shopService.FindShop(employee.getShopId().getId());
        } catch (Exception e) {
        }
        
        return shop;
    }

    public void setShop(Shop shop) {
        this.shop = shop;
    }

    public String getShowDate() {
        DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
        showDate = df.format(new Date());
        return showDate;
    }

    public void setShowDate(String showDate) {
        this.showDate = showDate;
    }

    public SaleProduct getSaleProduct() {
        return saleProduct;
    }

    public void setSaleProduct(SaleProduct saleProduct) {
        this.saleProduct = saleProduct;
    }

    public double getCalculateIgv() {
        double amount=0;
        if(listDetailSaleProduct!=null){
            for(DetailSaleProduct dsp: listDetailSaleProduct)
            {
                amount +=dsp.getAmount()*dsp.getPriceUnit();
            }
            System.out.println("igv= "+(saleProduct.getIgv()/100));
            calculateIgv = VarUtil.roundDouble(((saleProduct.getIgv()/100)*amount), 2);
        }
        return calculateIgv;
    }

    public void setCalculateIgv(double calculateIgv) {
        this.calculateIgv = calculateIgv;
    }

    public double getCalculateTotalAmount() {
        //double amount=0;
        if(listDetailSaleProduct!=null){
            calculateTotalAmount = VarUtil.roundDouble((getCalculateIgv()+getCalculateSubTotal()), 2);
        }
        return calculateTotalAmount;
    }

    public void setCalculateTotalAmount(double calculateTotalAmount) {
        this.calculateTotalAmount = calculateTotalAmount;
    }

    public double getCalculateSubTotal() {
        double amount=0;
        if(listDetailSaleProduct!=null){
            for(DetailSaleProduct dsp: listDetailSaleProduct)
            {
                amount +=dsp.getAmount()*dsp.getPriceUnit();
            }
            calculateSubTotal = VarUtil.roundDouble((amount), 2);
        }
        return calculateSubTotal;
    }

    public void setCalculateSubTotal(double calculateSubTotal) {
        this.calculateSubTotal = calculateSubTotal;
    }

    public String getSearchForCode() {
        return searchForCode;
    }

    public void setSearchForCode(String searchForCode) {
        this.searchForCode = searchForCode;
    }

    public String getSearchForName() {
        return searchForName;
    }

    public void setSearchForName(String searchForName) {
        this.searchForName = searchForName;
    }

    public Map<String, Object> getParameters() {
        System.out.println("shop : " + shop.getId());
        if (parameters == null) {
            parameters = new HashMap<>();
            if (shop.getId() != null) {
                parameters.put("shopId", shop.getId());
            }
            
        }
        return parameters;
    }

    public void setParameters(Map<String, Object> parameters) {
        this.parameters = parameters;
    }

    public String getNamedQuery() {
        return namedQuery;
    }

    public void setNamedQuery(String namedQuery) {
        this.namedQuery = namedQuery;
    }

    public Map<String, Object> getMapParam() {
        if (mapParam == null) {
            mapParam = new HashMap<>();
            if (shop.getId() != null) {
                mapParam.put("shopId", shop.getId());
            }
        }
        return mapParam;
    }

    public void setMapParam(Map<String, Object> mapParam) {
        this.mapParam = mapParam;
    }
    
    
    
}
